package com.wisdytech.ccdserver.bucket.serveice.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wisdytech.ccdserver.bucket.dao.IBucketDao;
import com.wisdytech.ccdserver.bucket.dao.IBucketRecordDao;
import com.wisdytech.ccdserver.bucket.dto.*;
import com.wisdytech.ccdserver.bucket.model.Bucket;
import com.wisdytech.ccdserver.bucket.model.BucketRecord;
import com.wisdytech.ccdserver.bucket.model.BucketRelation;
import com.wisdytech.ccdserver.bucket.serveice.IBucketRecordService;
import com.wisdytech.ccdserver.bucket.serveice.IBucketRelationService;
import com.wisdytech.ccdserver.bucket.serveice.IBucketService;
import com.wisdytech.ccdserver.bucket.serveice.IBucketTaskService;
import com.wisdytech.ccdserver.common.config.BucketConfig;
import com.wisdytech.ccdserver.common.config.MinioConfig;
import com.wisdytech.ccdserver.common.constant.TraceConstants;
import com.wisdytech.ccdserver.common.contants.CommonConstants;
import com.wisdytech.ccdserver.common.dto.FileDto;
import com.wisdytech.ccdserver.common.utils.*;
import com.wisdytech.common.bean.Filter;
import com.wisdytech.common.bean.MultiResultResponse;
import com.wisdytech.common.bean.UniqueResultResponse;
import com.wisdytech.common.execption.BaseErrorCode;
import com.wisdytech.common.execption.BaseServiceException;
import com.wisdytech.common.utils.SnowFlake;
import io.minio.MinioClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.rpc.RpcContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

@Slf4j
public class BucketServiceImpl extends ServiceImpl<IBucketDao, Bucket> implements IBucketService {

    @Value("${trace.api.ccdServerUrl}")
    private String ccdServerUrl;

    @Value("${trace.api.ccdServerTenUrl}")
    private String ccdServerTenUrl;

    @Value("${trace.api.ccdServerBucketUrl}")
    private String ccdServerBucketUrl;

    @Value("${trace.api.ccdServerDirectoryUrl}")
    private String ccdServerDirectoryUrl;

    @Value("${trace.api.ccdServerByPageUrl}")
    private String ccdServerByPageUrl;

    @Value("${trace.api.packModuleNonpaged}")
    private String packModuleNonpaged;

    @Value("${trace.api.baseUrl}")
    private String baseUrl;

    @Autowired
    private BucketConfig bucketConfig;

    @Autowired
    private MinioClient client;

    @Autowired
    private HttpUtils httpUtils;

    @Resource
    private SnowFlake snowFlake;

    @Autowired
    private MinioConfig minioConfig;

    @Resource
    private IBucketDao bucketDao;

    @Resource
    private IBucketRecordDao bucketRecordDao;

    @Resource
    private IBucketRelationService bucketRelationService;

    @Resource
    IBucketRecordService bucketRecordService;

    @Resource
    IBucketTaskService bucketTaskService;

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    /**
     * @Description: 按照条件进行查询，并直接保存到本地
     * @Param: * @param null
     * @return: * @return null
     * @Author: SV00216491
     * @Date: 2024/4/22  11:23
     */


    public UniqueResultResponse getBucketList(Filter filter) throws Exception {

        String strBucket = bucketTaskService.checkBucketIsNull(filter);
        if (!StringUtils.isEmpty(strBucket)) {
            return UniqueResultResponse.fail("当前 " + strBucket + " 没有创建表，请先联系管理员创建表之后，再重试");
        }

        int searchCount = bucketTaskService.srarchPushtasks(filter);
        if (searchCount > 0) {
            return UniqueResultResponse.fail("当前查询的条件的数据已经下载过数据，请更换条件查询");
        }
        String taskId = snowFlake.nextStringId();

        Map<String, Object> queryParams = filter.getQueryMap();
        String originMtimeBegin = (String) queryParams.get("originMtimeBegin");
        String originMtimeEnd = (String) queryParams.get("originMtimeEnd");
        List<BucketRecord> bucketRecords = new ArrayList<>();
        if (!StringUtils.isEmpty(originMtimeBegin) && !StringUtils.isEmpty(originMtimeEnd)) {
            // 1、处理时间拆分对象，并组装成一个新的查询条件 - 按照时间和桶拆分处理的对象
            bucketRecords = dealBucketRecordList(filter, taskId);
        } else {
            // 2、处理图片目录选择， - 按照桶拆分处理的对象
            bucketRecords = dealBucketByPicturePathRecordList(filter, taskId);
        }
        // 2、保存任务信息
        bucketTaskService.saveBucketTask(filter, taskId);
        // 3、保存条件查询信息，并异步处理任务
        bucketRecordService.batchSaveBucketRecord(bucketRecords, taskId);

        return UniqueResultResponse.success(true);
    }


    /**
     * @Description: 推送数据
     * @Param: * @param filter
     * @return: * @return com.wisdytech.common.bean.UniqueResultResponse
     * @Author: SV00216491
     * @Date: 2024/4/3  12:07
     */
    @Override
    public UniqueResultResponse PushBuckets(Filter filter) throws IOException {
        Map<String, Object> queryParams = filter.getQueryMap();
        //插入之前，先保存查询条件
        bucketRecordService.SavePushRecords(filter);
        //查询返回结果
        //处理时间偏移量
        if (StringUtils.isEmpty((String) queryParams.get("timeOffset"))) {
            queryParams.put("timeOffset", "0");
        }
        if (StringUtils.isEmpty((String) queryParams.get("originMtimeBegin"))) {
            queryParams.put("timeOffset", "");
        }
        Map<String, Object> newQueryParams = dealTimeOffset(queryParams);
        String token = httpUtils.obtainApiToken();
        //查询返回结果,查询所有的请求路径
        String url = ccdServerUrl;
        String taskid = snowFlake.nextStringId();
        List<EsSource> esSources = searchByDetails(newQueryParams, token, url);
        //保存的动作异步处理
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                    List<Bucket> buckets = dealBucketList(esSources, taskid);
                    this.saveBatch(buckets);
                }
                , taskExecutor);
        future.join();
        return UniqueResultResponse.success(true);
    }

    /**
     * @Description: 导入批量插入的方法
     * @Param: * @param queryParams
     * @return: * @return com.wisdytech.common.bean.UniqueResultResponse
     * @Author: SV00216491
     * @Date: 2024/4/3  16:45
     */

    //处理时间偏移量
    public Map<String, Object> dealTimeOffset(Map<String, Object> queryParams) {
        String timeOffset = (String) queryParams.get("timeOffset");
        if (!StringUtils.isEmpty(timeOffset)) {
            // 处理时间函数，让时间函数向前偏移一定时间 queryParams
            String originMtimeBegin = (String) queryParams.get("originMtimeBegin");
            String originMtimeEns = (String) queryParams.get("originMtimeEnd");
            Date starDate = DateUtil.parse(originMtimeBegin);
            Date endDate = DateUtil.parse(originMtimeEns);
            //根据配置计算，向前偏移几分钟
            Date newStarDate = DateUtil.offset(starDate, DateField.SECOND, 0 - Integer.parseInt(timeOffset));
            //origin_mtime为UTC时间时间统一-8小时
            String newOriginMtimeBegin = DateUtil.format(DateUtil.offsetHour(newStarDate, -8), "yyyy-MM-dd HH:mm:ss");
            String newOriginMtimeEns = DateUtil.format(DateUtil.offsetHour(endDate, -8), "yyyy-MM-dd HH:mm:ss");
            queryParams.put("originMtimeBegin", newOriginMtimeBegin);
            queryParams.put("originMtimeEnd", newOriginMtimeEns);
        }
        return queryParams;
    }

    @Override
    public void PushBucketsBeatch(Map<String, Object> queryParams, String token, String taskid) {

        try {
            //查询返回结果,查询所有的请求路径
            String url = ccdServerUrl;
            List<EsSource> esSources = searchByDetails(queryParams, token, url);
            if (!CollectionUtils.isEmpty(esSources)) {
                List<Bucket> buckets = dealBucketList(esSources, taskid);
                this.saveBatch(buckets);
            }
        } catch (Exception e) {
            log.error("查询大数据平台报错", e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * @Description: 根据输入参数进行查询，是否已经进行了下载
     * @Param: * @param filter
     * @return: * @return void
     * @Author: SV00216491
     * @Date: 2024/4/3  12:41
     */

    public int srarchPushRecords(Filter filter) throws IOException {
        //前端的条件
        Map<String, Object> queryParams = filter.getQueryMap();
        String equipmentCode = (String) queryParams.get("equipmentCode");
        String originMtimeBegin = (String) queryParams.get("originMtimeBegin");
        String originMtimeEnd = (String) queryParams.get("originMtimeEnd");
        QueryWrapper<BucketRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("BUCKET", equipmentCode);
        queryWrapper.apply("(ORIGIN_MTIME_BEGIN  ='" + originMtimeBegin + "') = 1 ");
        queryWrapper.apply("(ORIGIN_MTIME_END  ='" + originMtimeEnd + "') = 1 ");
        return bucketRecordDao.selectCount(queryWrapper);
    }


    //集合处理  包含特殊字符换处理，格式转化，字段赋值等
    public List<Bucket> dealBucketList(List<EsSource> esSources, String taskid) {
        List<Bucket> buckets = esSources.stream().map(e -> {
            Bucket bucket = new Bucket();
            bucket.setId(snowFlake.nextStringId());
            String map = e.getMeta().replaceAll("Map", "").replaceAll("\\)", "").replaceAll("\\(", "").replaceAll("->", ";");
            List<String> strList = new ArrayList<>(Arrays.asList(map.split(",")));
            for (String str : strList) {
                if (str.contains("size")) {
                    String size = Arrays.asList(str.split(";")).get(1);
                    bucket.setSize(size);
                }
                if (str.contains("mtime")) {
                    String initMtime = Arrays.asList(str.split(";")).get(1).replaceAll("T", " ");
                    bucket.setMtime(initMtime.substring(0, initMtime.length() - 5));
                }
                continue;
            }
            bucket.setBucket(e.getBucket());
            bucket.setName(e.getName());
            bucket.setStatus(CommonConstants.SEARCH_FALSE);
            bucket.setTaskid(taskid);
            String username = RpcContext.getServiceContext().getAttachment("username");
            bucket.setCreateDate(new Date());
            bucket.setCreateUser(username);
            bucket.setDelFlag(CommonConstants.DEL_FALSE);
            bucket.setOriginMtime(e.getOriginMtime());
            return bucket;
        }).collect(Collectors.toList());
        return buckets;
    }

    /**
     * @Description: 过滤已经存在的bucket
     * @Param: * @param buckets
     * @return: * @return java.util.List<com.wisdytech.ccdserver.bucket.model.Bucket>
     * @Author: SV00216491
     * @Date: 2024/3/29  13:31
     */

    public void FilterByExist(List<Bucket> buckets) {
        // 数据库中查询的已经存在的bucket
        List<Bucket> newBuckets = new ArrayList<>();
        Map<String, List<Bucket>> exitBucketMap = buckets.stream().collect(Collectors.groupingBy(e -> e.getBucket()));
        exitBucketMap.forEach((key, value) -> {
            List<String> indexs = value.stream().map(e -> e.getBucket()).collect(Collectors.toList());
            //分组遍历不同分表桶中的数据
            List<Bucket> buckets1 = listByIndexAndBucket(indexs, key);
            if (!CollectionUtils.isEmpty(buckets)) {
                newBuckets.addAll(buckets1);
            }
        });
        //取差集，然后进行保存
        List<Bucket> noExistBuckets = buckets.stream().filter(item -> !newBuckets.contains(item)).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(noExistBuckets)) {
        }
        this.saveBatch(noExistBuckets);
    }

    /**
     * @param bucket 桶名称
     * @Description: 根据bucket  和  index查询已经存在的数据
     * @Param: * @param index  所用的集合
     * @return: * @return java.util.List<com.wisdytech.ccdserver.bucket.model.Bucket>
     * @Author: SV00216491
     * @Date: 2024/3/29  14:00
     */
    public List<Bucket> listByIndexAndBucket(List<String> index, String bucket) {
        QueryWrapper<Bucket> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("BUCKET", bucket);
        queryWrapper.in("NAME", index);
        return bucketDao.selectList(queryWrapper);
    }


    public List<EsSource> searchByDetails(Map<String, Object> queryParams, String token, String url) {
        String[] fields = {"equipmentCode"};

        String relationshipDataUrl = baseUrl.concat(url);
        //要将双引号处理成单引号
        TraceCommonUtils.doConditionLogicBySemicolon(queryParams, fields);
        //结果数据
        ResultDto resultDto = new ResultDto();
        if (!StringUtils.isEmpty(token)) {
            log.info("========开始查询数据=============" + JSONObject.toJSONString(queryParams));
            resultDto = httpUtils.searchFromBigData(relationshipDataUrl, queryParams, token);
            log.info("========结束查询数据=============");
        }
        String result1 = resultDto.getResult();
        if (StringUtils.isEmpty(result1)) {
            return Collections.EMPTY_LIST;
        }
        return JSONObject.parseArray(resultDto.getResult(), EsSource.class);
    }

    public BucketResultDto searchBucketsByName(Map<String, Object> queryParams, String token, String url) {
        String[] fields = {"equipmentCode"};

        String relationshipDataUrl = baseUrl.concat(url);
        //要将双引号处理成单引号
        //TraceCommonUtils.doConditionLogicBySemicolon(queryParams, fields);
        //结果数据
        ResultDto resultDto = new ResultDto();
        if (!StringUtils.isEmpty(token)) {
            resultDto = httpUtils.searchFromBigData(relationshipDataUrl, queryParams, token);
        }
        BucketResultDto br = new BucketResultDto();

        String result1 = resultDto.getResult();
        if (StringUtils.isEmpty(result1)) {
            br.setTotalNum(0);
            br.setEsSources(Collections.EMPTY_LIST);
        }
        List<EsSource> esSources = JSONObject.parseArray(resultDto.getResult(), EsSource.class);
        br.setTotalNum(resultDto.getCount());
        br.setEsSources(esSources);
        return br;
    }

    public BucketResultDto searchDirectAndCountByDetails(Map<String, Object> queryParams, String token, String url) {
        String relationshipDataUrl = baseUrl.concat(url);
        //结果数据
        ResultDto resultDto = new ResultDto();
        if (!StringUtils.isEmpty(token)) {
            resultDto = httpUtils.searchFromBigData(relationshipDataUrl, queryParams, token);
        }
        BucketResultDto br = new BucketResultDto();

        String result1 = resultDto.getResult();
        if (StringUtils.isEmpty(result1)) {
            br.setTotalNum(0);
            br.setEsSources(Collections.EMPTY_LIST);
        }
        List<EsSource> esSources = JSONObject.parseArray(resultDto.getResult(), EsSource.class);
        br.setTotalNum(resultDto.getCount());
        br.setEsSources(esSources);
        return br;
    }

    public BucketResultDto searchTenAndCountByDetails(Map<String, Object> queryParams, String token, String url) {
        String[] fields = {"equipmentCode"};

        String relationshipDataUrl = baseUrl.concat(url);
        //要将双引号处理成单引号
        TraceCommonUtils.doConditionLogicBySemicolon(queryParams, fields);
        //结果数据
        ResultDto resultDto = new ResultDto();
        if (!StringUtils.isEmpty(token)) {
            resultDto = httpUtils.searchFromBigData(relationshipDataUrl, queryParams, token);
        }
        BucketResultDto br = new BucketResultDto();

        String result1 = resultDto.getResult();
        if (StringUtils.isEmpty(result1)) {
            br.setTotalNum(0);
            br.setEsSources(Collections.EMPTY_LIST);
        }
        List<EsSource> esSources = JSONObject.parseArray(resultDto.getResult(), EsSource.class);
        br.setTotalNum(resultDto.getCount());
        br.setEsSources(esSources);
        return br;
    }

    //异常追溯就界面下载ccd批量导入模版数据
    @Override
    public UniqueResultResponse downloadCcdTemplate(Filter filter) throws Exception {
        //1、获取数据
        List<PackModuleCheckinfoDto> packModuleCheckinfoDtos = this.searchDetailsByFilter(filter);
        if (CollectionUtils.isEmpty(packModuleCheckinfoDtos)) {
            return UniqueResultResponse.success(true);
        }
        //2、解析数据
        //2.1、解析数据核对有没有对应的配置信息，
//        String notice = noticeBucketRealtions(packModuleCheckinfoDtos);
        String notice = noticeBucketRealtionsPlus(packModuleCheckinfoDtos);
        if (!StringUtils.isEmpty(notice)) {
            return UniqueResultResponse.fail(notice);
        }
        List<CcdBucketRecordDto> bucketRecords = dealListByStream(filter, packModuleCheckinfoDtos);
        LinkedList<CcdBucketRecordDto> HashRecordsList = new LinkedList<>(new HashSet<>(bucketRecords));
        //3、写成excel文件
        MultipartFile exportExcel = ExcelUtil.exportToMinIO(HashRecordsList, CcdBucketRecordDto.class, "导出数据", "ccd导入统计数据");
        //上传Excel
        if (exportExcel != null) {
            FileDto fileDto = MinioUtils.uploadFile(exportExcel, snowFlake, minioConfig, client);
            return UniqueResultResponse.success(fileDto);
        }
        return UniqueResultResponse.fail("文件导出失败");
    }

    //获取大数据平台已经去重的数据
    public List<PackModuleCheckinfoDto> searchDetailsByFilter(Filter filter) {
        // 根据前端传过来的条件， 进行数据获取。
        String productionDetailUrl = baseUrl.concat(this.packModuleNonpaged);
        Map<String, Object> queryParams = filter.getQueryMap();
        List<PackModuleCheckinfoDto> productionDetailVoList = new ArrayList<>();
        String[] fields = {"cellCode", "packCode", "moduleCode", "jzCode"};
        TraceCommonUtils.doConditionLogicByOther(queryParams, fields);
        try {
            //获取token
            String token = httpUtils.obtainApiToken();
            if (!StringUtils.isEmpty(token)) {
                ResultDto result = httpUtils.searchFromBigData(productionDetailUrl, queryParams, token);
                String results = result.getResult().toString();
                if (StringUtils.isEmpty(results)) {
                    return Collections.EMPTY_LIST;
                }
                productionDetailVoList = com.alibaba.fastjson.JSONArray.parseArray(result.getResult().toString(), PackModuleCheckinfoDto.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return productionDetailVoList;
    }

    public List<CcdBucketRecordDto> dealListByStream(Filter filter, List<PackModuleCheckinfoDto> packModuleCheckinfoDtos) {

        //获取配置的数据
        Map<String, BucketRelation> stringBucketRelationMap = bucketRelationService.dealListToMap();
        Map<String, Object> queryMap = filter.getQueryMap();
        String pictureName = (String) queryMap.get("pictureName");
        String timeOffsetBegin = (String) queryMap.get("timeOffsetBegin");
        String timeOffsetEnd = (String) queryMap.get("timeOffsetEnd");
        //性能优化了一下。
        List<CcdBucketRecordDto> BucketRecordExport = packModuleCheckinfoDtos.parallelStream().map(e -> {
            String lineCode = e.getLineCode();
            String jzOutputTime = e.getJzOutputTime();
            Date jzOutputDate = DateUtil.parse(jzOutputTime);
            //根据配置计算，向前偏移几分钟
            Date newStarDateBegin = DateUtil.offsetMinute(jzOutputDate, 0 - Integer.parseInt(timeOffsetBegin));
            Date newStarDateEnd = DateUtil.offsetMinute(jzOutputDate, Integer.parseInt(timeOffsetEnd));
            String jzOperationCode = e.getJzOperationCode();
            String key = lineCode + "-" + jzOperationCode;
            BucketRelation br = stringBucketRelationMap.get(key);
            CcdBucketRecordDto bucketRecord = new CcdBucketRecordDto();
            String bucketName = br.getOneCode() + "-" + br.getTwoCode() + "-" + br.getThreeCode() + "-" + e.getEquipmentCode().substring(e.getEquipmentCode().length() - 2);
            bucketRecord.setBucket(bucketName);
            bucketRecord.setPictureName(pictureName);
            bucketRecord.setOriginMtimeBegin(DateUtil.format(newStarDateBegin, "yyyy-MM-dd HH:mm:ss"));
            bucketRecord.setOriginMtimeEnd(DateUtil.format(newStarDateEnd, "yyyy-MM-dd HH:mm:ss"));
            return bucketRecord;
        }).collect(Collectors.toList());
        List<CcdBucketRecordDto> bucketRecords = new ArrayList<>();
        bucketRecords.addAll(BucketRecordExport);
        return bucketRecords;
    }

    //提醒没有配置的信息，需要提前配置
    public String noticeBucketRealtions(List<PackModuleCheckinfoDto> packModuleCheckinfoDtos) {
        //获取配置的数据
        Map<String, BucketRelation> stringBucketRelationMap = bucketRelationService.dealListToMap();
        String notice = null;
        for (PackModuleCheckinfoDto e : packModuleCheckinfoDtos) {
            String lineCode = e.getLineCode();
            String jzOperationCode = e.getJzOperationCode();
            String key = lineCode + "-" + jzOperationCode;
            BucketRelation br = stringBucketRelationMap.get(key);
            if (br == null) {
                return notice = "请联系开发团队相关人员配置bucket关联配置关系和分表信息";
            }
        }
        return notice;
    }

    //提醒没有配置的信息，需要提前配置,优化的方法
    public String noticeBucketRealtionsPlus(List<PackModuleCheckinfoDto> packModuleCheckinfoDtos) {
        //获取配置的数据
        List<String> customerKeys = bucketRelationService.dealListToList();
        List<String> currentKeys = packModuleCheckinfoDtos.stream().map(br -> br.getLineCode() + "-" + br.getJzOperationCode()).collect(Collectors.toList());
        boolean bool = customerKeys.containsAll(currentKeys);
        String notice = null;
        if (!bool) {
            return notice = "请联系开发团队相关人员配置bucket关联配置关系和分表信息";
        }
        return notice;
    }

    /**
     * @Description: 只查询10条数据和总数
     * @Param: * @param filter
     * @return: * @return com.wisdytech.common.bean.UniqueResultResponse
     * @Author: SV00216491
     * @Date: 2024/4/22  10:54
     */

    @Override
    public UniqueResultResponse getBucketListTen(Filter filter) throws Exception {
        Map<String, Object> queryParams = filter.getQueryMap();
        //处理时间偏移量
        if (StringUtils.isEmpty((String) queryParams.get("timeOffset"))) {
            queryParams.put("timeOffset", "0");
        }
        if (StringUtils.isEmpty((String) queryParams.get("originMtimeBegin"))) {
            queryParams.put("timeOffset", "");
        }
        Map<String, Object> newQueryParams = dealTimeOffset(queryParams);
        // 处理数据
        String token = httpUtils.obtainApiToken();
        BucketTenDto bucketTenDto = asyncDealBucketAndCount(newQueryParams, token);
        return UniqueResultResponse.success(bucketTenDto);
    }

    @Override
    public MultiResultResponse getBucketsByPage(Filter filter) throws Exception {
        long offsetNum = 0;
        long limitNum = 15;
        Map<String, Object> queryParams = filter.getQueryMap();
        if (filter != null) {
            offsetNum = filter.getPage() - 1;
            limitNum = filter.getLimit();
        }
        queryParams.put("offsetNum", offsetNum * limitNum);
        queryParams.put("limitNum", limitNum);

        if (StringUtils.isEmpty((String) queryParams.get("timeOffset"))) {
            queryParams.put("timeOffset", "0");
        }
        if (StringUtils.isEmpty((String) queryParams.get("originMtimeBegin"))) {
            queryParams.put("timeOffset", "");
        }

        MultiResultResponse multiResultResponse = new MultiResultResponse();
        //处理时间偏移量
        Map<String, Object> newQueryParams = dealTimeOffset(queryParams);
        // 处理数据
        String token = httpUtils.obtainApiToken();
        String url = ccdServerByPageUrl;
        BucketResultDto bucketResultDto = searchTenAndCountByDetails(newQueryParams, token, url);
        List<Bucket> buckets = dealBucketList(bucketResultDto.getEsSources(), null);
        BucketTenDto bucketTenDto = new BucketTenDto();
        bucketTenDto.setData(buckets);
        bucketTenDto.setTotalNum(bucketResultDto.getTotalNum());

        if (buckets == null || buckets.size() < 0) {
            return multiResultResponse;
        }
        long totalNum = bucketResultDto.getTotalNum();

        multiResultResponse.setRows(buckets);
        multiResultResponse.setTotal(totalNum);
        multiResultResponse.setTotalPages((totalNum + limitNum - 1) / limitNum);
        return multiResultResponse;
    }

    @Override
    public BucketTenDto getBucketsByPages(Filter filter) throws Exception {
        Map<String, Object> queryParams = filter.getQueryMap();
        //处理时间偏移量
        if (StringUtils.isEmpty((String) queryParams.get("timeOffset"))) {
            queryParams.put("timeOffset", "0");
        }
        if (StringUtils.isEmpty((String) queryParams.get("originMtimeBegin"))) {
            queryParams.put("timeOffset", "");
        }

        Map<String, Object> newQueryParams = dealTimeOffset(queryParams);
        // 处理数据
        String token = httpUtils.obtainApiToken();
        String url = ccdServerByPageUrl;
        BucketResultDto bucketResultDto = searchTenAndCountByDetails(newQueryParams, token, url);
        List<Bucket> buckets = dealBucketList(bucketResultDto.getEsSources(), null);
        BucketTenDto bucketTenDto = new BucketTenDto();
        bucketTenDto.setData(buckets);
        bucketTenDto.setTotalNum(bucketResultDto.getTotalNum());
        return bucketTenDto;
    }

    @Override
    public UniqueResultResponse getBucketsByName(Filter filter) throws Exception {
        Map<String, Object> queryParams = filter.getQueryMap();
        // 处理数据
        String token = httpUtils.obtainApiToken();

        //查询返回结果
        String url = ccdServerBucketUrl;
        BucketResultDto bucketResultDto = searchBucketsByName(queryParams, token, url);
        List<BucketDto> bucketName = new ArrayList<>();
        Hashtable hashtable = new Hashtable();
        for (EsSource esSource : bucketResultDto.getEsSources()) {
            String bucket = esSource.getBucket().replace("\n", "");
            if (!hashtable.containsKey(bucket)) {
                BucketDto bucketDto = new BucketDto();
                bucketDto.setBucket(bucket);
                bucketName.add(bucketDto);
                hashtable.put(bucket, bucket);
            }
        }
        //List<Bucket> buckets = dealBucketList(bucketResultDto.getEsSources(), null);
        BucketNameDto bucketTenDto = new BucketNameDto();
        bucketTenDto.setData(bucketName);
        bucketTenDto.setTotalNum(bucketName.size());

        return UniqueResultResponse.success(bucketTenDto);
    }

    @Override
    public UniqueResultResponse getDirectorys(Filter filter) throws Exception {
        Map<String, Object> queryParams = filter.getQueryMap();
        // 处理数据
        String token = httpUtils.obtainApiToken();

        //处理分页
        queryParams = dealPage(queryParams);

        //查询返回结果
        String url = ccdServerDirectoryUrl;
        BucketResultDto bucketResultDto = searchDirectAndCountByDetails(queryParams, token, url);
        List<BucketDto> directory = new ArrayList<>();
        for (EsSource esSource : bucketResultDto.getEsSources()) {
            BucketDto bucketDto = new BucketDto();
            bucketDto.setDirectoryName(esSource.getName());
            directory.add(bucketDto);
        }
        BucketNameDto bucketTenDto = new BucketNameDto();
        bucketTenDto.setData(directory);
        bucketTenDto.setTotalNum(bucketResultDto.getTotalNum());

        return UniqueResultResponse.success(bucketTenDto);
    }

    private Map<String, Object> dealPage(Map<String, Object> queryParams) {
        long offsetNum = 0;
        long limitNum = 15;
        if (queryParams.get("offsetNum") != null && queryParams.get("limitNum") != null) {
            offsetNum = Long.valueOf(queryParams.get("offsetNum").toString()) - 1;
            limitNum = Long.valueOf(queryParams.get("limitNum").toString());
        }
        queryParams.put("offsetNum", String.valueOf(offsetNum * limitNum));
        queryParams.put("limitNum", String.valueOf(limitNum));
        return queryParams;

    }

    @Override
    public UniqueResultResponse getImageUrl(Filter filter) throws Exception {
        Map<String, Object> queryParams = filter.getQueryMap();

        if (null == queryParams.get("bucket") || null == queryParams.get("name")) {
            return UniqueResultResponse.fail("桶名称和图片名称不能为空");
        }

        String bucket_name = queryParams.get("bucket").toString();
        String object_key = queryParams.get("name").toString();

        AmazonS3Utils.initS3Client(bucketConfig.getAccessKey(), bucketConfig.getSecretKey(), bucketConfig.getEndPoint());
        String url = AmazonS3Utils.uploadUrl(bucket_name, object_key);
        AmazonS3Utils.close();
        return UniqueResultResponse.success(url);
    }

    @Override
    public InputStream getImage(Filter filter) throws Exception {
        Map<String, Object> queryParams = filter.getQueryMap();

        String bucket_name = queryParams.get("bucket").toString();
        String object_key = queryParams.get("name").toString();

        AmazonS3Utils.initS3Client(bucketConfig.getAccessKey(), bucketConfig.getSecretKey(), bucketConfig.getEndPoint());
        InputStream inputStream = null;//AmazonS3Utils.downloadImage(bucket_name,object_key);
        AmazonS3Utils.close();
        return inputStream;
    }

    @Override
    public UniqueResultResponse getImageResult(Filter filter) throws Exception {
        Map<String, Object> queryParams = filter.getQueryMap();

        String bucket_name = queryParams.get("bucket").toString();
        String object_key = queryParams.get("name").toString();

        AmazonS3Utils.initS3Client(bucketConfig.getAccessKey(), bucketConfig.getSecretKey(), bucketConfig.getEndPoint());
        byte[] inputStream = AmazonS3Utils.downloadImage(bucket_name, object_key);
        AmazonS3Utils.close();
        return UniqueResultResponse.success(inputStream);
    }

    @Override
    public UniqueResultResponse manualOperationBucketTask(Filter filter) {
        Map<String, Object> queryMap = filter.getQueryMap();
        String taskId = (String) queryMap.get("taskId");
        if (StringUtils.isEmpty(taskId)) {
            return UniqueResultResponse.fail("请输入taskId");
        }
        Integer preCount = bucketRecordService.countBucketNumByTaskId(taskId);
        try {
            Thread.sleep(7000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Integer currentCount = bucketRecordService.countBucketNumByTaskId(taskId);
        if ((currentCount - preCount) > 0) {
            return UniqueResultResponse.fail("当前任务已经在执行，请勿重复执行");
        }
        bucketTaskService.updateInterRuptFlag(taskId);

        bucketRecordService.DealSyncBucketRecordDetails(taskId);

        return UniqueResultResponse.success(true);
    }

    @Override
    public void deleteByTaskId(List<BucketRecordDto> bucketRecordDtos) {
        bucketRecordDtos.stream().forEach(x -> {
            LambdaQueryWrapper<Bucket> queryWrapper = new LambdaQueryWrapper();
            queryWrapper.eq(Bucket::getTaskid, x.getTaskId());
            queryWrapper.eq(Bucket::getBucket, x.getBucket());
            this.baseMapper.delete(queryWrapper);
        });
    }


    /**
     * @param token
     * @Description: 处理请求的数据与总数
     * @Param: * @param newQueryParams
     * @return: * @return com.wisdytech.ccdserver.bucket.dto.BucketTenDto
     * @Author: SV00216491
     * @Date: 2024/4/23  10:51
     */

    public BucketTenDto asyncDealBucketAndCount(Map<String, Object> newQueryParams, String token) throws Exception {

        //查询返回结果，只查询10条的路径
        String url = ccdServerTenUrl;
        BucketResultDto bucketResultDto = searchTenAndCountByDetails(newQueryParams, token, url);
        List<Bucket> buckets = dealBucketList(bucketResultDto.getEsSources(), null);
        BucketTenDto bucketTenDto = new BucketTenDto();
        bucketTenDto.setData(buckets);
        bucketTenDto.setTotalNum(bucketResultDto.getTotalNum());
        return bucketTenDto;


    }

    public List<BucketRecord> dealBucketByPicturePathRecordList(Filter filter, String taskId) {
        //直接进行数据拆分，进行保存数据
        Map<String, Object> queryParams = filter.getQueryMap();
        String equipmentCode = (String) queryParams.get("equipmentCode");
        String pictureName = (String) queryParams.get("pictureName");
        List<String> eqcodes = new ArrayList<String>();
        if (equipmentCode.contains(",")) {
            eqcodes = Arrays.asList(equipmentCode.split(","));
        } else {
            eqcodes.add(equipmentCode);
        }
        List<BucketRecord> newList = new ArrayList<>();
        for (String eqcode : eqcodes) {
            BucketRecord br = new BucketRecord();
            br.setPictureName(pictureName);
            br.setTaskId(taskId);
            br.setCreateDate(new Date());
            String username = RpcContext.getServiceContext().getAttachment("username");
            br.setCreateUser(username);
            br.setPictureName(pictureName);
            br.setBucket(eqcode);
            newList.add(br);
        }
        return newList;
    }

    //根据时间和维度拆分
    public List<BucketRecord> dealBucketRecordList(Filter filter, String taskId) {
        //直接进行数据拆分，进行保存数据
        Map<String, Object> queryParams = filter.getQueryMap();
        String originMtimeBegin = (String) queryParams.get("originMtimeBegin");
        String originMtimeEnd = (String) queryParams.get("originMtimeEnd");
        String equipmentCode = (String) queryParams.get("equipmentCode");
        String pictureName = (String) queryParams.get("pictureName");
        List<DateSplitUtils.DateSplit> dateSplits = DateSplitUtils.splitDate(DateUtil.parseDateTime(originMtimeBegin), DateUtil.parseDateTime(originMtimeEnd), DateSplitUtils.IntervalType.MINUTE, 10);
        if (CollectionUtils.isEmpty(dateSplits)) {
            return Collections.EMPTY_LIST;
        }
        List<String> eqcodes = new ArrayList<String>();
        if (equipmentCode.contains(",")) {
            eqcodes = Arrays.asList(equipmentCode.split(","));
        } else {
            eqcodes.add(equipmentCode);
        }
        List<BucketRecord> newList = new ArrayList<>();
        for (DateSplitUtils.DateSplit dateSplit : dateSplits) {
            for (String eqcode : eqcodes) {
                BucketRecord br = new BucketRecord();
                br.setOriginMtimeBegin(dateSplit.getStartDateTimeStr());
                br.setPictureName(pictureName);
                br.setOriginMtimeEnd(dateSplit.getEndDateTimeStr());
                br.setTaskId(taskId);
                br.setCreateDate(new Date());
                String username = RpcContext.getServiceContext().getAttachment("username");
                br.setCreateUser(username);
                br.setPictureName(pictureName);
                br.setBucket(eqcode);
                newList.add(br);
            }
        }
        return newList;
    }

    @Override
    public MinitorBucketViewDto searchCountBucketByBucket(BucketTaskDto bucketTaskDto) {
        MinitorBucketViewDto mbv = new MinitorBucketViewDto();
        CompletableFuture<MinitorBucketViewDto> future01 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务1线程开始启动：" + Thread.currentThread().getName());
            MinitorBucketViewDto minitorBucketViewDto = this.baseMapper.searchCountPictureNumByBucket(bucketTaskDto);
            return minitorBucketViewDto;
        }, taskExecutor);
        CompletableFuture<MinitorBucketViewDto> future02 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务2线程开始启动：" + Thread.currentThread().getName());
            MinitorBucketViewDto minitorBucketViewDto1 = this.baseMapper.searchCountPictureTotalNumByBucket(bucketTaskDto);
            return minitorBucketViewDto1;
        }, taskExecutor);

        CompletableFuture<MinitorBucketViewDto> stringCompletableFuture = future01.thenCombineAsync(future02, (res1, res2) -> {
            mbv.setPictureNum(res1.getPictureNum());
            mbv.setPictureTotalNum(res2.getPictureTotalNum());
            return mbv;
        }, taskExecutor);
        MinitorBucketViewDto minitorBucketViewDto = null;
        try {
            minitorBucketViewDto = stringCompletableFuture.get();
        } catch (Exception e) {
            log.error("计算异常{}", e.getMessage());
            e.printStackTrace();
        }
        return minitorBucketViewDto;
    }

    @Override
    public  IPage<FileDto>  exportBucketsByPage(Filter filter, int rowLimit) throws Exception {
        Integer limit = 0;
        Integer page = 1;
        //记录数量超过，则分批次调用
        Integer maxSize = TraceConstants.MAX_SIZE;
        //每次请求的数据量
        Integer lines = TraceConstants.PAGE_COUNT;
        //超过分sheet(不分sheet，注释掉)
        //Integer sheetSize = BaseContants.SHEET_COUNT;
        Integer residueLines = 0;
        MultiResultResponse<Bucket> bucketMultiResultResponse = null;
        Boolean flag = true;
        List<Bucket> bucketList = new ArrayList<>();
        page = Math.toIntExact(filter.getPage());
        limit = Math.toIntExact(filter.getLimit());
        if (limit > maxSize) {
            filter.setLimit(lines);
            residueLines = limit;
            while (flag) {
                if (residueLines > lines) {
                    filter.setPage(page);
                    if (residueLines.equals(limit)) {
                        residueLines = limit - lines;
                    } else {
                        residueLines = residueLines - lines;
                    }
                    page = page + 1;
                } else {
                    filter.setPage(page);
                    filter.setLimit(residueLines);
                    flag = false;
                }
                bucketMultiResultResponse = this.getBucketsByPage(filter);
                List<Bucket> buckets = bucketMultiResultResponse.getRows();
                if (buckets != null && buckets.size() > 0) {
                    bucketList.addAll(buckets);
                }
            }
        } else {
            bucketMultiResultResponse = this.getBucketsByPage(filter);
            bucketList = bucketMultiResultResponse.getRows();
        }
        log.info("=============CCD检索导出====================" + bucketList.size());
        Long startTime = 0L;
        Long endTime = 0L;
        List<List> dataList = new ArrayList<>();
        dataList.add(bucketList);
        List<Class> classes = new ArrayList<>();
        classes.add(Bucket.class);
        List<String> nameList = new ArrayList<>();
        nameList.add("CCD检索");
        try {
            startTime = System.currentTimeMillis();
            MultipartFile multipartFile = ExcelUtil.writeExcelMultipleTablesNew(classes, dataList, nameList, rowLimit, "CCD检索");
            endTime = System.currentTimeMillis();
            IPage<FileDto> fileIPage = new Page<>();
            List<FileDto> fileList = new ArrayList<>();
            if (multipartFile != null) {
                FileDto fileDto = MinioUtils.uploadFile(multipartFile, snowFlake, minioConfig, client);
                fileList.add(fileDto);
                fileIPage.setRecords(fileList);
            }
            log.info("=================CCD检索导出==================" + (endTime - startTime) / 1000 + "秒");
            return fileIPage;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BaseServiceException(BaseErrorCode.ErrorCode.SYSTEM_ERROR);
        }
    }
}
